From 01f7c3a66cc11ac92bffc302e30053b5491884dc Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 1 Feb 2006 15:01:04 +0000 Subject: [PATCH] Proper fix for profile_pc on x86_64. Also enable CONFIG_FRAME_POINTER for dom0 and domU kernels. Signed-off-by: Christian Limpach --- buildconfigs/linux-defconfig_xen0_x86_32 | 2 +- buildconfigs/linux-defconfig_xen0_x86_64 | 2 +- buildconfigs/linux-defconfig_xenU_x86_32 | 2 +- buildconfigs/linux-defconfig_xenU_x86_64 | 2 +- .../arch/i386/kernel/time-xen.c | 24 ++++++++++++++----- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/buildconfigs/linux-defconfig_xen0_x86_32 b/buildconfigs/linux-defconfig_xen0_x86_32 index 245f74f960..a8efa792b8 100644 --- a/buildconfigs/linux-defconfig_xen0_x86_32 +++ b/buildconfigs/linux-defconfig_xen0_x86_32 @@ -1228,7 +1228,7 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set -# CONFIG_FRAME_POINTER is not set +CONFIG_FRAME_POINTER=y CONFIG_EARLY_PRINTK=y # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_KPROBES is not set diff --git a/buildconfigs/linux-defconfig_xen0_x86_64 b/buildconfigs/linux-defconfig_xen0_x86_64 index c6a4c24ede..e140ede4ad 100644 --- a/buildconfigs/linux-defconfig_xen0_x86_64 +++ b/buildconfigs/linux-defconfig_xen0_x86_64 @@ -1173,7 +1173,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_FS is not set -# CONFIG_FRAME_POINTER is not set +CONFIG_FRAME_POINTER=y # CONFIG_CHECKING is not set # CONFIG_INIT_DEBUG is not set # CONFIG_KPROBES is not set diff --git a/buildconfigs/linux-defconfig_xenU_x86_32 b/buildconfigs/linux-defconfig_xenU_x86_32 index 2180a714fc..ca3b4eb52c 100644 --- a/buildconfigs/linux-defconfig_xenU_x86_32 +++ b/buildconfigs/linux-defconfig_xenU_x86_32 @@ -518,7 +518,7 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set -# CONFIG_FRAME_POINTER is not set +CONFIG_FRAME_POINTER=y CONFIG_EARLY_PRINTK=y # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_KPROBES is not set diff --git a/buildconfigs/linux-defconfig_xenU_x86_64 b/buildconfigs/linux-defconfig_xenU_x86_64 index 5f5b171cae..32244b357c 100644 --- a/buildconfigs/linux-defconfig_xenU_x86_64 +++ b/buildconfigs/linux-defconfig_xenU_x86_64 @@ -895,7 +895,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_FS is not set -# CONFIG_FRAME_POINTER is not set +CONFIG_FRAME_POINTER=y # CONFIG_INIT_DEBUG is not set # CONFIG_KPROBES is not set diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c index 32a53bfaae..b3a0a64b80 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c @@ -58,6 +58,7 @@ #include #include #include +#include #include "mach_time.h" @@ -541,22 +542,33 @@ unsigned long long sched_clock(void) } #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) -#ifdef __x86_64__ -#define REG_BP rbp -#else -#define REG_BP ebp -#endif unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); +#ifdef __x86_64__ + /* Assume the lock function has either no stack frame or only a single word. + This checks if the address on the stack looks like a kernel text address. + There is a small window for false hits, but in that case the tick + is just accounted to the spinlock function. + Better would be to write these functions in assembler again + and check exactly. */ + if (in_lock_functions(pc)) { + char *v = *(char **)regs->rsp; + if ((v >= _stext && v <= _etext) || + (v >= _sinittext && v <= _einittext) || + (v >= (char *)MODULES_VADDR && v <= (char *)MODULES_END)) + return (unsigned long)v; + return ((unsigned long *)regs->rsp)[1]; + } +#else if (in_lock_functions(pc)) return *(unsigned long *)(regs->REG_BP + 4); +#endif return pc; } EXPORT_SYMBOL(profile_pc); -#undef REG_BP #endif irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -- 2.30.2